package com.nwpu.vote.parser;

import java.io.IOException;
import java.io.InputStream;
import java.util.Date;

import javax.jdo.JDOObjectNotFoundException;
import javax.jdo.PersistenceManager;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.fileupload.util.Streams;
import org.apache.commons.io.IOUtils;

import com.google.appengine.api.datastore.Blob;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;

import com.nwpu.vote.control.VotePersistentImpl;
import com.nwpu.vote.model.*;
import com.nwpu.vote.util.*;

public class VoteParser implements IVoteParser{

	public Vote parse(HttpServletRequest req) throws InvalidNewVoteException{
		
		String title = null;
		String creator = null;
		String department = null;
		Date createDate = null;
		String startDate = null;
		String finishDate = null;
		String description = null;
		String tags = null;
		
		com.google.appengine.api.datastore.Blob filebody = null;
		
		// Check that we have in a new vote request
		boolean isUserSelectAFile = false;
		boolean isMultipart = ServletFileUpload.isMultipartContent(req);
		if(isMultipart){
			// Create a new file upload handler
			ServletFileUpload upload = new ServletFileUpload();
			// Parse the request
			FileItemIterator iter;
			try {
				iter = upload.getItemIterator(req);
				while (iter.hasNext()) {
				    FileItemStream item = iter.next();
				    InputStream stream = item.openStream();
				    if (!item.isFormField()) {
				    	isUserSelectAFile  = true;
				        filebody = new Blob(IOUtils.toByteArray(stream)); // Handle the uploaded file
				    }else{
				    	if("title".equals(item.getFieldName())){
				    		title = Streams.asString(stream);
				    	}else if("creator".equals(item.getFieldName())){
				    		creator = Streams.asString(stream);
				    		if(creator.length() <= 0){
				    			//TODO set current logging in user as the creator
				    		}
				    	}else if("department".equals(item.getFieldName())){
				    		department = Streams.asString(stream);
				    	}else if("startDate".equals(item.getFieldName())){
				    		startDate = Streams.asString(stream);
				    	}else if("finishDate".equals(item.getFieldName())){
				    		finishDate = Streams.asString(stream);
				    	}else if("description".equals(item.getFieldName())){
				    		description = Streams.asString(stream);
				    	}else if("tags".equals(item.getFieldName())){
				    		tags = Streams.asString(stream);
				    	}
				    }
				}
			} catch (FileUploadException e) {
				throw new InvalidNewVoteException(e);
			} catch (IOException e) {
				throw new InvalidNewVoteException(e);
			}
		}
		
		if(!isUserSelectAFile){
			throw new InvalidNewVoteException("");
		}
		
		createDate = new Date();
		//TODO should be current logging-in user's key instead of anonymous
		Vote vote = new Vote(KeyFactory.createKey("anonymous", -1), department, title, createDate,
				new Date(startDate), new Date(finishDate), description);
		
		//create relationships among vote and tags...
		if(tags != null){
			String[] tagList = tags.split(" ");
			if(tagList.length>0) {
				for(String tag : tagList){
					if (!"".equals(tag.trim())){
						String tagname = tag.trim();
						Key key = KeyFactory.createKey(Tag.class.getSimpleName(), tagname);
						PersistenceManager pm = PMF.get().getPersistenceManager();
					
						Tag tagObj = null;
						try{
							tagObj = pm.getObjectById(Tag.class, KeyFactory.keyToString(key));
						}catch(JDOObjectNotFoundException e){
							tagObj = new Tag(tagname, "");
							tagObj.setKey(key);
							tagObj.addTaggedVoteKey(vote);
							//TODO not correct, the reference from tag to related files are not stored...
						
							try {
								VotePersistentImpl.instance.save(tagObj);
							} catch (PersistentException e1) {
								throw new InvalidNewVoteException(e1);
							}
						}
						
						vote.addTag(tagObj);
					}
				}
			}
		}
		
		return vote;
	}
}
